package core.proto.search;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.DocumentListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import core.proto.AllComponents;
import core.proto.InfoViz;
import core.proto.Util;
import core.util.logging.UserLogWriter;
import core.util.logging.constants.Action;
import core.util.logging.constants.Location;


import prefuse.util.ui.JSearchPanel;
import prefuse.util.ui.JSearchPanel.CancelButton;

import static app.constants.CollabVizConstants.*;


/**
 * This class represents the standard search bar UI we use. 
 *
 * It does not contain the actual search functionality. 
 * 
 * To add outter check
 */
public class SearchBar extends JPanel
{
	private static final long serialVersionUID = -4698815339116283668L;
	private JLabel searchLabel;
	private JTextField searchField;
	private SearchCancelButton button; 
	private boolean searchTimerBool = false;
	
	private HashSet<Integer> activeKeys = new HashSet<Integer>();
	
	private Timer timer = new Timer(0, null);

	public SearchBar(){
		initUI();
	}

	public MouseAdapter createUserLogClickListener(final Location loc){
		MouseAdapter adapter = new MouseAdapter(){
			public void mouseClicked(MouseEvent me){
				///UserLogWriter.log2("Clear search query", loc, Action.CLEARQUERY);
				if(me.getClickCount() == 1){
					UserLogWriter.log2(Action.CLICK, loc.toString(), "Search Box", "null", getSearchText().replace(",", "."), "null", "null", "null");
				}
				else{
					UserLogWriter.log2(Action.DOUBLECLICK, loc.toString(), "Search Box", "null", getSearchText().replace(",", "."), "null", "null", "null");
				}
			}
		};
		return adapter;
	}
	
	public void addUserLogClickListener (final Location loc) {
		searchField.addMouseListener(createUserLogClickListener(loc));
		button.addMouseListener(createUserLogClickListener(loc));
	}


	public void addDocumentListener(DocumentListener dl){
		searchField.getDocument().addDocumentListener(dl);
	}
	
	public JTextField getSearchField(){
		return searchField;
	}
	
	public  void addPropertyListenerSearchField(Object o){
		searchField.addPropertyChangeListener((PropertyChangeListener) o);
	}
	
	public void addMapSearchListener(){
		searchField.addKeyListener(new KeyAdapter() {
			          public void keyPressed(KeyEvent e) {
			            int key = e.getKeyCode();
			            if (key == KeyEvent.VK_ENTER) {
			               AllComponents.performMapSearch(searchField.getText());
			               }
			            }
			          }
			       );
	}


	private void initUI(){
		searchLabel = new JLabel("search >>");

		searchField = new JTextField(15);
		searchField.setBorder(BorderFactory.createEmptyBorder( 5, 5, 4, 0 ));
		searchField.setDragEnabled(false);

		button = new SearchCancelButton(searchField);

		Box box = new Box(BoxLayout.X_AXIS);
		box.add(searchLabel);
		box.add( Box.createHorizontalStrut(3) );

		Box searchBox = new Box(BoxLayout.X_AXIS);


		searchBox.add(searchField);
		searchBox.add( Box.createHorizontalStrut(3) );
		searchBox.add(button);
		searchBox.add( Box.createHorizontalStrut(3) );
		searchBox.setOpaque(true);
		searchBox.setBackground(Color.white);
		searchBox.setBorder(BorderFactory.createLineBorder(Color.black));
		searchBox.setPreferredSize(new Dimension(SEARCH_BOX_WIDTH, SEARCH_BOX_HEIGHT));
		box.add(searchBox);
		this.add(box);
	}
	
	private String getSearchText(){
		return searchField.getText();
	}

	public void addUserTypingListener(final Location loc) {
		searchField.addKeyListener(new KeyListener() {

			@Override
			public void keyPressed(KeyEvent arg0) {
				activeKeys.add(arg0.getKeyCode());
				
				
				 if(activeKeys.contains(KeyEvent.VK_CONTROL) && activeKeys.contains(KeyEvent.VK_C)){
					 UserLogWriter.log2(Action.KEYCOPY, loc.toString(), "Search Box", "null", getSearchText().replace(",", "."), "null", "null", "null");
					}
				 else{
					timer.stop();
					
					int delay = 1000; //milliseconds
					  ActionListener taskPerformer = new ActionListener() {
					      public void actionPerformed(ActionEvent evt) {
					    	  UserLogWriter.log2(Action.KEYTYPE, loc.toString(), "Search Box", "null", getSearchText().replace(",", "."), "null", "null", "null");
					      }
					  };
					 timer = new Timer(delay, taskPerformer);
					 timer.setRepeats(false);
					 timer.start();
				 }
				 
				
					if(activeKeys.contains(KeyEvent.VK_CONTROL) && activeKeys.contains(KeyEvent.VK_V)){
						UserLogWriter.log2(Action.KEYPASTE, loc.toString(), "Search Box", "null", getSearchText().replace(",", "."), "null", "null", "null");
					}
			}

			@Override
			public void keyReleased(KeyEvent arg0) {
				activeKeys.remove(arg0.getKeyCode());
			}

			@Override
			public void keyTyped(KeyEvent arg0) {

			}
		
		});
		
	}
}
